#define USE_AT_NETWORK_HTTP 1

#define GSM_PIN_RX 19    // 网络模块-接收
#define GSM_PIN_TX 20    // 网络模块-发送
#define GSM_PIN_POWER 3  // 网络模块-开关机控制管脚(低电平有效)
#define GSM_PIN_WAKEUP 8 // 网络模块-唤醒控制管脚(低电平有效)

#include <base_psram.h>
#include <base_define.h>
#include <AtNetworkWithEC800.h>

AtNetworkDeviceExample *device;

AtNetworkHttpExample *http;

// ------------------------------------------------
// 多线程任务函数
// ------------------------------------------------
/**
 * 网络模块数据获取核心线程
 */
void mThreadWithEc(void *pvParameters) {
  log_d("Network IMEI: %s", device->imei);
  log_d("Network IPV4: %s", device->ipv4);
  log_d("Network IPV6: %s", device->ipv6);
  log_d("Network Recv Thread start!");

  while (device != nullptr) {
    if (device->device_lock()) {
      device->wait(500, NULL);

      device->device_unlock();
    }

    delay(50);
  }
}

/**
 * 如果是N4R8 PSRAM需要选择OSPI
 * 如果是N4R2 PSRAM需要选择QSPI
 */
void setup() {
  Serial.begin(115200);
  log_d("System ready");

  // ----------------------------------------------------------------------------------
  // 内存配置初始化
  // ----------------------------------------------------------------------------------
  if (!psramInit() || !psramFound()) {
    log_e("PSRAM Init: ERROR!");
  }

  // 初始化串口
  Serial1.begin(115200, SERIAL_8N1);

  // 初始化
  device = new AtNetworkDeviceExample(&Serial1);
  http = new AtNetworkHttpExample(device);

  // 管脚挂载
  pinMode(GSM_PIN_WAKEUP, OUTPUT);
  pinMode(GSM_PIN_POWER, OUTPUT);

  digitalWrite(GSM_PIN_WAKEUP, LOW);
  digitalWrite(GSM_PIN_POWER, LOW);

  // 初始化网络模块，并注册网络
  if (!device->connect(30)) {
    log_e("Network init: ERROR!");

    delay(60000L);

    esp_restart();
    return;
  }

  // 启动数据获取任务 & 以及各种测试线程任务
  xTaskCreatePinnedToCore(mThreadWithEc, "mThreadWithEc", 65536, NULL, 2, NULL, 1);
}

size_t httpCallback(size_t length, char *body) {
  Serial.println("------------------------------");
  Serial.println(body);
}

void loop() {
  log_d("System Free Psram: %d", ESP.getFreePsram());
  log_d("System Free Heap: %d", ESP.getFreeHeap());

  if (device->device_lock()) {
    http->get(httpCallback, "https://www.virens.cn");

    device->device_unlock();
  }

  delay(30000);
}